<template>
  <Teleport to="body">
    <Transition
      enter-active-class="transition-opacity duration-300"
      enter-from-class="opacity-0"
      enter-to-class="opacity-100"
      leave-active-class="transition-opacity duration-300"
      leave-from-class="opacity-100"
      leave-to-class="opacity-0"
    >
      <div
        v-if="modelValue"
        class="fixed inset-0 z-50 overflow-y-auto"
        @click="handleBackdropClick"
      >
        <!-- 背景遮罩 -->
        <div class="fixed inset-0 bg-black bg-opacity-50 transition-opacity" />

        <!-- 模态框容器 -->
        <div class="flex min-h-full items-center justify-center p-4">
          <Transition
            enter-active-class="transition-all duration-300"
            enter-from-class="opacity-0 scale-95 translate-y-4"
            enter-to-class="opacity-100 scale-100 translate-y-0"
            leave-active-class="transition-all duration-300"
            leave-from-class="opacity-100 scale-100 translate-y-0"
            leave-to-class="opacity-0 scale-95 translate-y-4"
          >
            <div
              v-if="modelValue"
              :class="[
                'relative bg-white rounded-lg shadow-xl transform transition-all',
                sizeClasses,
                'max-h-[90vh] flex flex-col'
              ]"
              @click.stop
            >
              <!-- 模态框头部 -->
              <div
                v-if="title || $slots.header"
                class="flex items-center justify-between p-6 border-b border-gray-200"
              >
                <div class="flex items-center">
                  <slot name="header">
                    <h3 class="text-lg font-semibold text-gray-900">
                      {{ title }}
                    </h3>
                  </slot>
                </div>
                <button
                  v-if="closable"
                  @click="handleClose"
                  class="text-gray-400 hover:text-gray-600 transition-colors"
                >
                  <i class="w-6 h-6 mdi:close" />
                </button>
              </div>

              <!-- 模态框内容 -->
              <div class="flex-1 overflow-y-auto p-6">
                <slot />
              </div>

              <!-- 模态框底部 -->
              <div
                v-if="$slots.footer"
                class="flex items-center justify-end space-x-3 p-6 border-t border-gray-200"
              >
                <slot name="footer" />
              </div>
            </div>
          </Transition>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted } from 'vue'

interface Props {
  modelValue?: boolean
  title?: string
  size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'
  closable?: boolean
  closeOnBackdrop?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: true,
  size: 'md',
  closable: true,
  closeOnBackdrop: true
})

const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  close: []
}>()

// 尺寸样式类
const sizeClasses = computed(() => {
  const sizeMap = {
    sm: 'w-full max-w-md',
    md: 'w-full max-w-lg',
    lg: 'w-full max-w-2xl',
    xl: 'w-full max-w-4xl',
    '2xl': 'w-full max-w-6xl'
  }
  return sizeMap[props.size]
})

// 处理关闭
const handleClose = () => {
  emit('update:modelValue', false)
  emit('close')
}

// 处理背景点击
const handleBackdropClick = () => {
  if (props.closeOnBackdrop) {
    handleClose()
  }
}

// 处理 ESC 键
const handleEscKey = (event: KeyboardEvent) => {
  if (event.key === 'Escape' && props.closable) {
    handleClose()
  }
}

// 防止页面滚动
const preventScroll = (event: Event) => {
  event.preventDefault()
}

onMounted(() => {
  if (props.modelValue) {
    document.addEventListener('keydown', handleEscKey)
    document.body.style.overflow = 'hidden'
    document.addEventListener('wheel', preventScroll, { passive: false })
    document.addEventListener('touchmove', preventScroll, { passive: false })
  }
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleEscKey)
  document.body.style.overflow = ''
  document.removeEventListener('wheel', preventScroll)
  document.removeEventListener('touchmove', preventScroll)
})
</script>